﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Design;
using System.Windows.Forms;
using System.Reflection;
using System.Collections;
using ProgNetComponents.NamedObjects;
using ProgNetComponents.Design.Serialization;

namespace ProgNetComponents.Design.Editors
{
    
    public class NamedCollectionEditor : CollectionEditor
    {
        protected virtual bool GenerateConstantClass
        {
            get { return false; }
        }
        protected virtual string ConstantClassName
        {
            get
            {
                if (this.CollectionItemType != null)
                    return this.CollectionItemType.Name + "Names";
                return string.Empty;
            }
        }
        protected virtual string ConstantClassNamespace
        {
            get { return ProgNetComponents.Constants.ProgNetConstNamespace; }
        }
        protected IServiceProvider _Provider = null;

        protected CollectionForm _Form = null;
        protected ListBox listbox = null;
        protected TableLayoutPanel _ButtonPanel = null;
        protected System.Drawing.Size StandardButtonSize
        {
            get { return new System.Drawing.Size(75, 23); }
        }
        protected List<string> errors = new List<string>();
        protected void AddError(string error)
        {
            if (!errors.Contains(error))
                errors.Add(error);
        }

        public NamedCollectionEditor(Type type)
            : base(type)
        {

        }

        public virtual bool AllowCopy
        {
            get { return true; }
        }
        protected virtual bool AllowAddOrRemove
        {
            get { return true; }
        }
        protected virtual bool AllowChangeOrder
        {
            get { return true; }
        }

        private DialogResult formResult = DialogResult.Cancel;
        protected void AddButton(Button btn)
        {
            if (_ButtonPanel != null)
            {
                int count  = _ButtonPanel.Controls.Count;
                int rows = _ButtonPanel.RowCount;
                int col = 2;
                if (count == rows * 2)
                {
                    _ButtonPanel.RowStyles.Add(new RowStyle(_ButtonPanel.RowStyles[0].SizeType, _ButtonPanel.RowStyles[0].Height));
                    col = 0;
                }
                _ButtonPanel.Controls.Add(btn, col, _ButtonPanel.RowCount);
            }
        }
        protected override CollectionForm CreateCollectionForm()
        {
            _Form = base.CreateCollectionForm();
            _Form.FormClosing += new FormClosingEventHandler(_Form_FormClosing);
            _Form.Load += new EventHandler(_Form_Load);
            if (_Form.Controls["overArchingTableLayoutPanel"] != null)
            {
                listbox = _Form.Controls["overArchingTableLayoutPanel"].Controls["listbox"] as ListBox;
                _ButtonPanel = _Form.Controls["overArchingTableLayoutPanel"].Controls["addRemoveTableLayoutPanel"] as TableLayoutPanel;
                try
                {
                    Button okButton =_Form.Controls["overArchingTableLayoutPanel"].Controls["okCancelTableLayoutPanel"].Controls["okButton"] as Button;
                    if (okButton != null)
                        okButton.Click += new EventHandler(okButton_Click);
                }
                catch { }
            }
            if (!AllowChangeOrder)
            {
                _Form.Controls["overArchingTableLayoutPanel"].Controls["upButton"].Visible = false;
                _Form.Controls["overArchingTableLayoutPanel"].Controls["downButton"].Visible = false;
            }
            if (_ButtonPanel != null)
            {
                if (!AllowAddOrRemove)
                {
                    _ButtonPanel.Controls["addButton"].Visible = false;
                    _ButtonPanel.Controls["removeButton"].Visible = false;
                }
            }
            if (_ButtonPanel != null && AllowCopy && CollectionItemType.IsAccesibleForm("System.ICloneable"))
            {
                Button b = new Button();
                b.Margin = _ButtonPanel.Controls[0].Margin;
                b.Padding = _ButtonPanel.Controls[0].Padding;
                b.Dock = DockStyle.Fill;
                b.Text = "Copy";
                b.Click += new EventHandler(b_Click);
                AddButton(b);
            }
            return _Form;
        }
        public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, IServiceProvider provider, object value)
        {
            _Provider = provider;
            return base.EditValue(context, provider, value);
        }
        void okButton_Click(object sender, EventArgs e)
        {
            formResult = DialogResult.OK;
        }

        void _Form_Load(object sender, EventArgs e)
        {
            formResult = DialogResult.Cancel;
        }
        protected virtual void ValidateCollection(object collection)
        {
            
        }

        private bool ValidateAll(object collection)
        {
            errors.Clear();
            ValidateCollection(collection);

            bool result = errors.Count == 0;
            if (!result)
                MessageBox.Show(errors.AsSingleString());
            return result;
        }
        private void _Form_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (formResult == DialogResult.OK)
            {
                e.Cancel = !ValidateAll(_Form.EditValue);
                if (e.Cancel)
                {
                    _Form.EditValue = _Form.EditValue;
                }
                else
                {
                    if (GenerateConstantClass && ConstantClassNamespace.IsNotNull() && ConstantClassName.IsNotNull())
                    {
                        List<string> l = new List<string>();
                        IList list = _Form.EditValue as IList;
                        foreach (object o in list)
                        {
                            if (o is INamedObject)
                                l.Add((o as INamedObject).Name);
                        }
                        ProjectHelper.AddConstantStringClass(_Provider, ConstantClassNamespace, ConstantClassName, l);
                    }
                }
            }
            formResult = DialogResult.Cancel;
        }

        private void b_Click(object sender, EventArgs e)
        {
            if (listbox != null)
            {
                object listItem = listbox.SelectedItem;
                if (listItem != null)
                {
                    object value = listItem.GetPropertyValue("Value");
                    if (value != null && value is ICloneable)
                    {

                        List<object> l = new List<object>();
                        l.Add((value as ICloneable).Clone());
                        _Form.RunMethod("AddItems", new object[] { l });
                    }
                }
            }
        }

        protected override bool CanRemoveInstance(object value)
        {
            if (!AllowAddOrRemove)
                return false;
            return base.CanRemoveInstance(value);
        }
    }
}
